import {clearTimeout,  setTimeout} from "timers";




function isPromise(p:any) {
    return p && Object.prototype.toString.call(p) === "[object Promise]";
}

export class TimeoutPromise<T> extends Promise<T> {
    constructor(cbOrPromise:any, ms = 30 * 1000, hint = 'PTIMEOUT', exitCondition?:any) {
        super(()=>{});

        let timeout:  ReturnType<typeof setTimeout>;
        let wrapperPromise = Promise.race([
            isPromise(cbOrPromise) ? cbOrPromise : new Promise(cbOrPromise),
            new Promise((resolve, reject) => {
                timeout = setTimeout(() => {
                    if (exitCondition) {
                        exitCondition.exist = true;
                    }
                    reject(new Error(hint));
                }, ms);
            }),
        ]);

        return wrapperPromise.then((data) => {
            clearTimeout(timeout);
            return data;
        }).catch((error) => {
            clearTimeout(timeout);
            throw error; // if timeout, reject the hint error
        })

    }
}